package com.stone.java8.pattern.command;

/**
 * desc   :
 * author : stone
 * email  : aa86799@163.com
 * time   : 08/03/2017 21 18
 */
public class Test {
    public static void main(String[] args) {
        /*
        一个命令者 接口， 定义 一个统一执行命令的抽象方法
        每个具体命令者都实现 命令者接口，并依赖一个 接收者对象，  命令的执行代理给接收者来执行
        调用者类，依赖一个命令者接口对象，由命令者接口来执行。 多态传入不同的具体命令者， 最终由接收者采取不同的执行方式
         */

        Test t = new Test();
        Editor editor = new Editor() {
            @Override
            public void save() {
                System.out.println("save");
            }

            @Override
            public void delete() {
                System.out.println("delete");
            }

            @Override
            public void open() {
                System.out.println("open");
            }

            @Override
            public void close() {
                System.out.println("close");
            }
        };

        /*
        原始调用方式
         */
        new Invoker(new OpenAction(editor)).invoke();
        new Invoker(new CloseAction(editor)).invoke();
        new Invoker(new SaveAction(editor)).invoke();
        new Invoker(new DeleteAction(editor)).invoke();

        /*
        lambda简化IAction
         */
        new Invoker(() -> editor.open()).invoke();
        new Invoker(() -> editor.delete()).invoke();
        new Invoker(() -> editor.delete()).invoke();
        new Invoker(() -> editor.delete()).invoke();

        /*
        将invoke方法，直接定义出来，原始调用方式
         */
        t.invoke(new OpenAction(editor));
        t.invoke(new CloseAction(editor));
        t.invoke(new SaveAction(editor));
        t.invoke(new DeleteAction(editor));

        /*
        将invoke方法，直接定义出来，并使用lambda
         */
        t.invoke(new IAction() {//原始匿名内部类方式
            @Override
            public void perform() {
                editor.open();
            }
        });
        t.invoke(() -> editor.open());
        t.invoke(() -> editor.close());
        t.invoke(() -> editor.save());
        t.invoke(() -> editor.delete());

    }

    static class Invoker {
        private IAction action;

        public Invoker(IAction action) {
            this.action = action;
        }

        public void invoke() {
            this.action.perform();
        }
    }

    private void invoke(IAction action) {
        action.perform();
    }
}
